package com.ms.p2p.plugin.payment.fuyou;


import com.ms.common.exception.NoticeException;
import com.ms.common.utils.MsDateUtils;
import com.ms.p2p.entity.account.AccountRecharge;
import com.ms.p2p.entity.system.PayMethod;
import com.ms.p2p.plugin.payment.AbstractPaymentPlugin;
import com.ms.p2p.plugin.payment.IPaymentEvent;
import net.sf.json.JSONObject;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class FuyouPCrzPayment extends AbstractPaymentPlugin implements IPaymentEvent {


    @Override
    public void register() {

    }

    @Override
    public String onPay(Integer userId, BigDecimal money, HashMap other,HttpServletRequest request) throws Exception {
        PayMethod payment = payMethodService.findById(getId());
        AccountRecharge rechargeOrder = BuildReCharge(userId, money, payment);
        String weburl = settingService.findValueByCode("weburl");
        String urlStr = "http://" + weburl + "";
        String noticeurl =  urlStr+payMethodValueService.findByName("fuyou.pcrznotify").getParamValue();
        String returnurl =  urlStr+payMethodValueService.findByName("fuyou.pcrzreturn").getParamValue();
        String page_notify_url = returnurl;
        String back_notify_url = noticeurl;
        String rsaStr = payMethodValueService.findByName("fuyou.mchnt_cd").getParamValue() + "|" + userId + "|" +rechargeOrder.getTrade_no()
                + "|" + rechargeOrder.getMoney().multiply(new BigDecimal(100)) + "|" + other.get("bank_cardno") + "|" + other.get("realname") + "|0" + "|" + other.get("id_card_no")
                + "|" + page_notify_url + "|" + back_notify_url;
        logger.error("***********************"+rsaStr+"***********************");
        byte[] bytesKey = (new BASE64Decoder()).decodeBuffer(payMethodValueService.findByName("fuyou.privatekey").getParamValue().trim());
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(bytesKey);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature signature = Signature.getInstance("MD5WithRSA");
        signature.initSign(priKey);
        signature.update(rsaStr.getBytes("GBK"));
        String RSA = (new BASE64Encoder()).encodeBuffer(signature.sign());
        LinkedHashMap map  = new LinkedHashMap();
        map.put("mchnt_cd",payMethodValueService.findByName("fuyou.mchnt_cd").getParamValue());
        map.put("order_id",rechargeOrder.getTrade_no());
        map.put("order_amt",rechargeOrder.getMoney().multiply(new BigDecimal(100)));
        map.put("user_type",0);
        map.put("page_notify_url",page_notify_url);
        map.put("back_notify_url",back_notify_url);
        map.put("card_no",other.get("bank_cardno"));
        map.put("cert_type",0);
        map.put("cert_no", other.get("id_card_no"));
        map.put("cardholder_name", other.get("realname"));
        map.put("user_id", userId);
        map.put("RSA", RSA);
        return buildPostRequest( map,  payMethodValueService.findByName("fuyou.pcrzurl").getParamValue(),request);

    }

    @Override
    public String onReturn(HttpServletRequest request) throws Exception {

        logger.info("——————————————富友快捷支付异步回调开始"+MsDateUtils.getTimeToday());
        logger.info("——————————————富友快捷支付publickey="+payMethodValueService.findByName("fuyou.publickey").getParamValue().trim());
        request.setCharacterEncoding("UTF-8");
        String mchnt_cd = nvl(request.getParameter("mchnt_cd"));
        String order_id = nvl(request.getParameter("order_id"));
        String order_date = nvl(request.getParameter("order_date"));
        String order_amt = nvl(request.getParameter("order_amt"));
        String order_st = nvl(request.getParameter("order_st"));
        String order_pay_code = nvl(request.getParameter("order_pay_code"));
        String order_pay_msg = nvl(request.getParameter("order_pay_msg"));
        String user_id = nvl(request.getParameter("user_id"));
        String fy_ssn = nvl(request.getParameter("fy_ssn"));
        String card_no = nvl(request.getParameter("card_no"));
        String pay_type = nvl(request.getParameter("pay_type"));
        String RSA = nvl(request.getParameter("RSA"));
        String signDataStr = mchnt_cd + "|" + user_id + "|" +
                order_id + "|" + order_amt + "|" + order_date + "|" + card_no + "|" + fy_ssn ;
        byte[] keyBytes = (new BASE64Decoder()).decodeBuffer(payMethodValueService.findByName("fuyou.publickey").getParamValue().trim());
        // 构造X509EncodedKeySpec对象
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        // KEY_ALGORITHM 指定的加密算法
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        // 取公钥匙对象
        PublicKey pubKey = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initVerify(pubKey);
        signature.update(signDataStr.getBytes("gbk"));
        // 验证签名是否正常
        boolean ret = signature.verify((new BASE64Decoder()).decodeBuffer(RSA));
        String out_trade_no = order_id;
        if ("0000".equals(order_pay_code)) {
            if (ret) {
                OnlineReturn(out_trade_no, "在线认证充值-富友支付");
                logger.info("——————————————富友认证支付回调成功");
            } else {
                logger.info("——————————————富友pc认证支付同步回调失败，错误原因：验签失败");
            }
        } else {
            logger.info("——————————————富友pc认证支付同步回调失败,错误原因"+order_pay_msg);
        }
        return null;
    }

    @Override
    public String getTradeNo(Map<String, String> params) throws Exception {
        return null;
    }

    @Override
    public String getType() {
        return "1";
    }

    @Override
    //id需要与paymethod id一样
    public String getId() {
        return "56";
    }

    @Override
    //名称需要与包明一样
    public String getName() {
        return "fuyoupcrz";
    }

    @Override
    public String getVersion() {
        return "1.0.0";
    }

    @Override
    public String getAuthor() {
        return "daimajia";
    }

    @Override
    public void perform(Object... params) {

    }

    public static String MD5Encode(String origin) {
        origin = origin.trim();
        String resultString = null;

        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            resultString = byteArrayToHexString(md.digest(resultString.getBytes("UTF-8")));
        } catch (Exception var3) {
            ;
        }

        return resultString;
    }

    public static String byteArrayToHexString(byte[] b) {
        StringBuffer resultSb = new StringBuffer();

        for(int i = 0; i < b.length; ++i) {
            resultSb.append(byteToHexString(b[i]));
        }

        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if(b < 0) {
            n = b + 256;
        }

        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
    private static final String[] hexDigits = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    public static String nvl(String aStr) {
        if (aStr == null || "null".equals(aStr.trim())) {
            return "";
        } else {
            return aStr.trim().toString();
        }
    }
}
